/*
 * Copyright (C) 2021 Huawei Device Co., Ltd.
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.me.relex.photodraweeview;

import com.me.relex.photodraweeview.iml.OnEnableListener;
import com.me.relex.photodraweeview.utils.Util;
import ohos.agp.animation.Animator;
import ohos.agp.animation.AnimatorProperty;
import ohos.agp.animation.AnimatorValue;
import ohos.agp.components.AttrSet;
import ohos.agp.components.Component;
import ohos.agp.components.Image;
import ohos.agp.window.service.DisplayAttributes;
import ohos.agp.window.service.DisplayManager;
import ohos.app.Context;
import ohos.media.image.PixelMap;
import ohos.multimodalinput.event.TouchEvent;

/**
 * 自定义手势滑动、双指缩放、单指跟随滚动动画的image
 *
 * @since 2021-03-27
 */
public class PhotoView extends Image implements Component.TouchEventListener, Component.DoubleClickedListener {
    /**
     * 双指缩小的最小值
     */
    private static final float MIN_SCALE = 0.50f;

    /**
     * 整体放大倍数3
     */
    private static final float MAX_SCALE_COMPONENT = 3.0f;

    private static final int ANIMATOR_DURATION = 400;
    /**
     * 默认是1
     */
    private float scaleNum = 1;
    private float mScaleStep = 0.0f;
    /**
     * 当前放大的倍数
     */
    private float scaleFloat = 0.0f;
    /**
     * down、up的x，y坐标
     */
    private float startX;
    private float startY;
    private float endX;
    private float endY;
    private float baseValue;
    /**
     * 记录上一次双指事件中手指移动值
     */
    private float mLastMoveValue = -1;
    private OnEnableListener mEnableListener;
    private boolean isPageSlider = false;
    private boolean isRecyclerView = false;

    /**
     * 记录上一次move结束的时间
     */
    private long mMoveErrorTimeMillis = 0;

    /**
     * down touch 时间点
     */
    private long mDownTimeMillis = 0;

    /**
     * up touch 时间点
     */
    private long mUpTimeMillis = 0;

    /**
     * 惯性加速度的时间点
     */
    private long mInertiaTimeMillis = 0;

    /**
     * 是否是三指或者三指以上操作
     */
    private boolean isMultiFinger = false;

    /**
     * 当前手指的触碰事件，0：未触碰；1：单指；2：双指；
     */
    private int mCurrentPointer = 0;

    private DisplayAttributes mDisplayAttributes;
    private float mCurrentPositionX;
    private float mCurrentPositionY;
    private float mLastPositionX = 0;
    private float mLastPositionY = 0;
    private float mLastWidthBoundary = 0;
    private float mLastHeightBoundary = 0;

    private int c = 0;
    private int d = 0;

    /**
     * 构造函数
     *
     * @param context 上下文
     */
    public PhotoView(Context context) {
        this(context, null);
    }

    /**
     * 构造函数
     *
     * @param context 上下文
     * @param attr    自定义属性
     */
    public PhotoView(Context context, AttrSet attr) {
        this(context, attr, "");
    }

    /**
     * 构造函数
     *
     * @param context  上下文
     * @param attr     自定义属性
     * @param defStyle 自定义样式
     */
    public PhotoView(Context context, AttrSet attr, String defStyle) {
        super(context, attr, defStyle);
        init();
    }

    private void init() {
        super.setScaleMode(ScaleMode.STRETCH);

        setDoubleClickedListener(this);
        setTouchEventListener(this);

        mDisplayAttributes = DisplayManager.getInstance().getDefaultDisplay(getContext()).get().getAttributes();
    }

    @Override
    public void setPixelMap(int resId) {
        super.setPixelMap(resId);
    }

    @Override
    public void setPixelMap(PixelMap pixelMap) {
        super.setPixelMap(pixelMap);
    }

    @Override
    public void setImageAndDecodeBounds(int resId) {
        super.setImageAndDecodeBounds(resId);
    }

    /**
     * 双指缩放图片，当图片处于缩小阶段，在双指离开时需要执行复位动画，监听动画结果
     *
     * @since 2021-03-27
     */
    private class StateChangedListener implements Animator.StateChangedListener {
        @Override
        public void onStart(Animator animator) {
        }

        @Override
        public void onStop(Animator animator) {
        }

        @Override
        public void onCancel(Animator animator) {
        }

        @Override
        public void onEnd(Animator animator) {
            // 双指离开时，统计当前缩放的比例，为下一次单指滑动作准备
            scaleNum = getScaleX();
        }

        @Override
        public void onPause(Animator animator) {
        }

        @Override
        public void onResume(Animator animator) {
        }
    }

    private float getScaleStep() {
        return mScaleStep;
    }

    void setScaleStep(float scaleStep) {
        this.mScaleStep = scaleStep;
    }

    @Override
    public boolean onTouchEvent(Component component, TouchEvent touchEvent) {
        switch (touchEvent.getAction()) {
            case TouchEvent.PRIMARY_POINT_DOWN:
                mLastMoveValue = -1;
                mCurrentPointer = 0;
                baseValue = 0;
                isMultiFinger = false;
                mDownTimeMillis = System.currentTimeMillis();
                startX = touchEvent.getPointerScreenPosition(0).getX();
                startY = touchEvent.getPointerScreenPosition(0).getY();

                // 得到整个图片左上角的坐标
                mCurrentPositionX = getContentPositionX();
                mCurrentPositionY = getContentPositionY();
                if (isPageSlider || isRecyclerView) {
                    mEnableListener.onEnable(true);
                }
                break;
            case TouchEvent.PRIMARY_POINT_UP:
                onTouchEventUp(component, touchEvent);
                c = 0;
                d = 0;
                baseValue = 0;
                break;
            case TouchEvent.POINT_MOVE:
                // 当前鼠标移动到的坐标
                float pointerX = touchEvent.getPointerScreenPosition(0).getX();
                float pointerY = touchEvent.getPointerScreenPosition(0).getY();
                if (mCurrentPointer == 0 && touchEvent.getPointerCount() == 1
                        && (Math.abs(pointerX - startX) > 10 || Math.abs(pointerY - startY) > 10)) {
                    mCurrentPointer = 1;
                } else if (mCurrentPointer == 0 && touchEvent.getPointerCount() >= 2) {
                    mCurrentPointer = 2;
                } else {
                }
                if (touchEvent.getPointerCount() == 1 && mCurrentPointer == 1) {
                    // 单指操作
                    singlePointerMove(touchEvent);
                } else if (touchEvent.getPointerCount() == 2 && mCurrentPointer == 2 && !isMultiFinger) {
                    doublePointerMove(component, touchEvent);
                } else if (touchEvent.getPointerCount() >= 3) {
                    isMultiFinger = true;
                    doublePointerMove(component, touchEvent);
                } else {
                }
                break;
            case TouchEvent.OTHER_POINT_DOWN:
                baseValue = 0;
                break;
            default:
                break;
        }
        return true;
    }

    /**
     * up touch event
     *
     * @param component  上下文
     * @param touchEvent 事件
     */
    private void onTouchEventUp(Component component, TouchEvent touchEvent) {
        if (mCurrentPointer == 2) {
            if (component.getScaleX() < 1) {
                AnimatorProperty animator = component.createAnimatorProperty();
                animator.setCurveType(Animator.CurveType.DECELERATE).scaleX(1).scaleY(1)
                        .setDuration(ANIMATOR_DURATION);
                animator.setStateChangedListener(new StateChangedListener());
                animator.start();
            } else {
                scaleNum = (getScaleX() - 1) / getScaleStep();
            }

            // 图片复位（优先判断宽度是否小于当前屏幕宽度）
            if (getWidth() * getScaleX() <= mDisplayAttributes.width) {
                if (isRecyclerView) {
                    setPosition(0, 0);
                } else {
                    setPosition(0, (mDisplayAttributes.height - getHeight()) / 2);
                }
            }
        }
        endX = touchEvent.getPointerPosition(0).getX();
        endY = touchEvent.getPointerPosition(0).getY();
        if (isPageSlider || isRecyclerView) {
            mEnableListener.onEnable(true);
        }

        float moveX = touchEvent.getPointerScreenPosition(0).getX() - startX;
        float moveY = touchEvent.getPointerScreenPosition(0).getY() - startY;

        if (System.currentTimeMillis() - mUpTimeMillis < 200 &&
                System.currentTimeMillis() - mInertiaTimeMillis > 200 &&
                (Math.abs(moveX) < 100 || Math.abs(moveY) < 100)
        ) {
            setScaleImage(component, true);
            return;
        }
        mUpTimeMillis = System.currentTimeMillis();

        if ((Math.abs(moveX) > 100 || Math.abs(moveY) > 100) && mCurrentPointer == 1) {
            animationInertia(moveX, moveY);
        }
        mCurrentPointer = 0;
    }

    /**
     * 单指滑动
     *
     * @param touchEvent 事件参数
     */
    private void singlePointerMove(TouchEvent touchEvent) {
        if (!isRecyclerView && getWidth() * scaleFloat <= mDisplayAttributes.width) {
            return;
        }
        mLastPositionX = 0;
        mLastWidthBoundary = 0;
        mLastPositionY = 0;
        mLastHeightBoundary = 0;

        // 当前鼠标移动到的坐标
        float pointerX = touchEvent.getPointerScreenPosition(0).getX();
        float pointerY = touchEvent.getPointerScreenPosition(0).getY();

        if (pointerX - startX > 50 || pointerY - startY > 50) {
            mMoveErrorTimeMillis = System.currentTimeMillis();
        }

        // startX - 鼠标down的坐标；toX - 鼠标焦点移动的距离/4
        int toX = (int) (pointerX - startX);
        int toY = (int) (pointerY - startY);

        int heightBoundary = (int) (getHeight() * (getScaleY() - 1) / 2);
        int widthBoundary = (int) (getWidth() * (getScaleX() - 1) / 2);

        int positionX = (int) (mCurrentPositionX + toX);
        int positionY = (int) (mCurrentPositionY + toY);

        if (Math.abs(toX) > 1 && toX > 0 && (positionX >= widthBoundary)) {
            positionX = widthBoundary;
        } else if (Math.abs(toX) > 1 && toX < 0 && positionX < -widthBoundary) {
            positionX = -widthBoundary;
        } else {
        }

        if (Math.abs(toY) > 1 && toY > 0 && (positionY >= heightBoundary)) {
            positionY = heightBoundary;
        } else if (!isRecyclerView && Math.abs(toY) > 1 && toY < 0
                && (heightBoundary - positionY >= getHeight() * scaleFloat - mDisplayAttributes.height)) {
            positionY = heightBoundary - (int) (getHeight() * scaleFloat - mDisplayAttributes.height);
        } else if (isRecyclerView && Math.abs(toY) > 1 && toY < 0 && (positionY < -heightBoundary)) {
            positionY = -heightBoundary;
        } else {
        }

        // 在touch事件生效前，判断是否已滚动到最左边还是最右边，如果已滚动到，则需要把事件交给PageSlider
        if (setSliderMoveTouch(widthBoundary, toX)) {
            return;
        }

        // 解决recyclerView上下滑动跟图片滑动冲突
        if (setRecyclerMoveTouch(heightBoundary, toY)) {
            return;
        }

        if (!isRecyclerView && getHeight() * scaleFloat <= mDisplayAttributes.height) {
            positionY = (int) mCurrentPositionY;
        }
        setPosition(positionX, positionY);
    }

    /**
     * 双指操作
     *
     * @param component  Component
     * @param touchEvent 事件
     */
    private void doublePointerMove(Component component, TouchEvent touchEvent) {
        // 双指间距
        float value = calculateDist(touchEvent);

        // 第一次移动，处理一些图片的初始数据
        if (baseValue == 0) {
            baseValue = value;
        } else {
            if (value - baseValue >= 50 || value - baseValue <= -50 || c >= 4) {
                c ++;
                if (c < 4) {
                    return;
                }
                d = 0;
                float scale = 0;
                if (mLastMoveValue == -1) {
                    mLastMoveValue = value;
                    return;
                }

                if (Math.abs(value - mLastMoveValue) > 200) {
                    return;
                }

                float newScale = getScaleX()*(1 + ((value - mLastMoveValue) / mDisplayAttributes.width));
                float diffValue = value - mLastMoveValue;
                if (value > mLastMoveValue) {
                    scale = newScale;
                } else {
                    if (newScale > MIN_SCALE) {
                        // 控制缩小比例
                        scale = newScale;
                    } else {
                        // 最低缩小到0.5
                        scale = MIN_SCALE;
                    }
                }

                mLastMoveValue = value;
                if (scale > MAX_SCALE_COMPONENT) {
                    if (scaleFloat < MAX_SCALE_COMPONENT) {
                        component.setScale(MAX_SCALE_COMPONENT, MAX_SCALE_COMPONENT);
                    }
                    scaleFloat = MAX_SCALE_COMPONENT;
                    c = 0;
                    return;
                }
                scaleFloat = scale;

                if (scaleFloat < 1) {
                    mLastPositionX = 0;
                    mLastWidthBoundary = 0;
                    mLastPositionY = 0;
                    mLastHeightBoundary = 0;
                    component.setScale(scaleFloat, scaleFloat);
                    mComponentParent.postLayout();
                } else {
                     setMoveScale(component, diffValue, scaleFloat);
                }
            } else {
                d ++;
                if (d < 4) {
                    return;
                }
                c = 0;
                singlePointerMove(touchEvent);
            }
        }
    }

    /**
     * 计算两指触摸点之间的距离
     *
     * @param touchEvent touch事件
     * @return 两点之间的距离
     */
    private float calculateDist(TouchEvent touchEvent) {
        float pointX = touchEvent.getPointerPosition(0).getX() - touchEvent.getPointerPosition(1).getX();
        float pointY = touchEvent.getPointerPosition(0).getY() - touchEvent.getPointerPosition(1).getY();

        // 计算两点的距离
        return (float) Math.sqrt(pointX * pointX + pointY * pointY);
    }

    /**
     * 计算屏幕对角线长度
     *
     * @return 对角线值
     */
    private double getScreenDiagonal() {
        int width = mDisplayAttributes.width;
        int height = mDisplayAttributes.height;
        return Math.sqrt(width * width + height * height);
    }

    @Override
    public void onDoubleClick(Component component) {
    }

    /**
     * 设置缩放
     *
     * @param component  动画控件
     * @param isAnimator 是否需要执行动画
     */
    private void setScaleImage(Component component, boolean isAnimator) {
        if (System.currentTimeMillis() - mMoveErrorTimeMillis < 500) {
            return;
        }
        if (scaleFloat < MAX_SCALE_COMPONENT) {
            // 其他地方主动设置放大倍数
            if (getScaleStep() > 0) {
                scaleFloat = 1 + scaleNum * getScaleStep();
                scaleNum++;
            } else {
                scaleFloat = (float) Math.floor(getScaleX()) + 1;
            }
        } else {
            scaleFloat = 1;
            scaleNum = 1;
        }
        if (scaleFloat == 1) {
            if (isRecyclerView) {
                setPosition(0, 0);
            } else {
                setPosition(0, (mDisplayAttributes.height - getHeight()) / 2);
            }
        }

        if (isAnimator) {
            AnimatorProperty anim = new AnimatorProperty(component);
            anim.setCurveType(Animator.CurveType.DECELERATE)
                    .scaleX(scaleFloat)
                    .scaleY(scaleFloat)
                    .setDuration(ANIMATOR_DURATION);
            anim.start();
        } else {
            component.setScale(scaleFloat, scaleFloat);
        }
    }

    /**
     * 处理image move中 父布局是上下滚动的情况
     *
     * @param heightBoundary 放大的高度的一半
     * @param toY            y轴的移动
     * @return 是否拦截move事件
     */
    private boolean setRecyclerMoveTouch(int heightBoundary, int toY) {
        if (!isRecyclerView) {
            return false;
        }

        if (heightBoundary != 0 && Math.abs(toY) > 1 && toY > 0 && heightBoundary == getComponentPosition().top) {
            // 到顶部
            mEnableListener.onEnable(true);
            return true;
        } else if (heightBoundary != 0 && Math.abs(toY) > 1 && toY < 0
                && heightBoundary + getComponentPosition().bottom == getHeight()) {
            // 到底部
            mEnableListener.onEnable(true);
            return true;
        } else if (heightBoundary == 0) {
            mEnableListener.onEnable(true);
            return true;
        } else {
            mEnableListener.onEnable(false);
        }
        return false;
    }

    /**
     * 处理image move中 父布局是左右滚动的情况
     *
     * @param widthBoundary 放大的宽度的一半
     * @param toX           x轴的移动
     * @return 是否拦截move事件
     */
    private boolean setSliderMoveTouch(int widthBoundary, int toX) {
        if (!isPageSlider) {
            return false;
        }
        if (widthBoundary != 0 && Math.abs(toX) > 1 && toX > 0 && widthBoundary == getComponentPosition().left) {
            // 到最左边
            mEnableListener.onEnable(true);
            return true;
        } else if (widthBoundary != 0 && Math.abs(toX) > 1 && toX < 0
                && widthBoundary + getComponentPosition().right == getWidth()) {
            // 到最右边
            mEnableListener.onEnable(true);
            return true;
        } else if (widthBoundary == 0) {
            mEnableListener.onEnable(true);
            return true;
        } else {
            mEnableListener.onEnable(false);
        }
        return false;
    }

    /**
     * 设置滑动冲突时事件的传递顺序
     *
     * @param enableListener 回调参数
     */
    public void setOnEnableListener(OnEnableListener enableListener) {
        mEnableListener = enableListener;
    }

    /**
     * 设置该自定义Image是否被用在PageSlider，用以区别是否需要处理滑动冲突
     *
     * @param isSlider 是否参数
     */
    public void isPageSlider(boolean isSlider) {
        this.isPageSlider = isSlider;
    }

    /**
     * 设置是否有外层的recyclerView的滚动冲突
     *
     * @param isRecycler 是否设置列表滚动
     */
    public void isRecyclerView(boolean isRecycler) {
        this.isRecyclerView = isRecycler;
    }

    /**
     * 获取手指抬起时的X轴坐标
     *
     * @return 点击的x轴坐标
     */
    public String getTouchUpX() {
        float moveX = 0;
        if (getContentPositionX() < 0) {
            moveX = (endX - getContentPositionX() * 2) / (getWidth() * getScaleX());
        } else {
            moveX = endX / (getWidth() * getScaleX());
        }
        return Util.formatFloatToStr(moveX, "0.0000000");
    }

    /**
     * 获取手指抬起时的Y轴坐标
     *
     * @param top 距离屏幕顶部距离
     * @return 计算点击的Y轴坐标
     */
    public String getTouchUpY(int top) {
        float moveY = 0;
        if (getHeight() * getScaleY() <= mDisplayAttributes.height) {
            moveY = endY / (getHeight() * getScaleY());
        } else {
            moveY = (endY + (getHeight() * (getScaleY() - 1)) / 2 - getContentPositionY())
                    / (getHeight() * getScaleY());
        }
        return Util.formatFloatToStr(moveY, "0.0000000");
    }

    /**
     * 重置效果
     *
     * @param component Component
     */
    public void initPhotoView(Component component) {
        scaleFloat = 3;
        setScaleImage(component, false);
    }

    /**
     * 上层传递的双击事件
     *
     * @param component Component
     */
    public void doubleClick(Component component) {
    }

    /**
     * 惯性动画
     *
     * @param moveX x轴移动
     * @param moveY y轴移动
     */
    private void animationInertia(float moveX, float moveY) {
        mInertiaTimeMillis = System.currentTimeMillis();
        if (System.currentTimeMillis() - mDownTimeMillis < 200) {
            int widthBoundary = (int) (getWidth() * (getScaleX() - 1) / 2);
            int heightBoundary = (int) (getHeight() * (getScaleY() - 1) / 2);
            float positionX = getContentPositionX();
            float positionY = getContentPositionY();
            AnimatorValue animatorValue = new AnimatorValue();
            animatorValue.setDuration(500);
            animatorValue.setCurveType(Animator.CurveType.DECELERATE);
            animatorValue.setValueUpdateListener((animatorValue1, v) -> {
                int y = 0;
                int x = 0;
                if (Math.abs(moveX * 5 + positionX) < widthBoundary) {
                    x = (int) (positionX + moveX * 5 * v);
                } else {
                    x = (int) (positionX + ((moveX > 0 ? widthBoundary : -widthBoundary) - positionX) * v);
                }
                if (isRecyclerView) {
                    if (Math.abs(moveY * 5 + positionY) < heightBoundary) {
                        y = (int) (positionY + moveY * 5 * v);
                    } else {
                        y = (int) (positionY + ((moveY > 0 ? heightBoundary : -heightBoundary) - positionY) * v);
                    }
                } else {
                    int maxHeight = heightBoundary
                            - (int) (getHeight() * scaleFloat - mDisplayAttributes.height);
                    y = (int) (positionY + ((moveY > 0 ? heightBoundary : maxHeight) - positionY) * v);
                }

                if (getWidth() * getScaleX() < mDisplayAttributes.width || Math.abs(moveX) < 100) {
                    x = (int) positionX;
                }
                if (getHeight() * getScaleY() < mDisplayAttributes.height || Math.abs(moveY) < 100) {
                    if (!isRecyclerView) {
                        y = (int) positionY;
                    }
                }
                setPosition(x, y);
            });
            animatorValue.start();
        }
    }

    /**
     * 处理双指缩放
     *
     * @param component component
     * @param diffValue diffValue
     * @param scale     缩放比例
     */
    private void setMoveScale(Component component, float diffValue,float scale) {
        if (scale > getScaleX()) {
            mLastPositionX = 0;
            mLastWidthBoundary = 0;
            mLastPositionY = 0;
            mLastHeightBoundary = 0;
            component.setScale(scale, scale);
            return;
        }

        if (diffValue == 0) {
            return;
        }

        // 处理X轴临界值情况
        int scaleDevX = (int) (getWidth() * (diffValue / mDisplayAttributes.width) * getScaleX() / 2);
        double getNowPositionX = getContentPositionX() > 0 ?
                (getContentPositionX() + scaleDevX) : (getContentPositionX() - scaleDevX);
        int x = mLastPositionX == 0 ? (int) getNowPositionX : (int) mLastPositionX;
        mLastWidthBoundary = mLastWidthBoundary == 0 ?
                (getWidth() * (getScaleX() - 1) / 2) : (mLastWidthBoundary + scaleDevX);
        if (x - mLastWidthBoundary >= 1 && x > 0) {
            x = (int) mLastWidthBoundary;
        } else if (x < 0 && x + mLastWidthBoundary <= -1) {
            x = (int) -mLastWidthBoundary;
        } else {
        }

        // 处理Y轴临界值情况
        int scaleDevY = (int) (getHeight() * (diffValue / mDisplayAttributes.width) * getScaleY() / 2);
        double getNowPositionY = getContentPositionY() > 0 ?
                (getContentPositionY() + scaleDevY) : (getContentPositionY() - scaleDevY);
        int y = mLastPositionY == 0 ? (int) getNowPositionY : (int) mLastPositionY;
        mLastHeightBoundary = mLastHeightBoundary == 0 ?
                (getHeight() * (getScaleY() - 1) / 2) : (mLastHeightBoundary + scaleDevY);
        if (mLastHeightBoundary < 0) {
            return;
        }
        boolean isbeyondScreen = getHeight() * getScaleY() > mDisplayAttributes.height ? true : false;
        float diffHeight = getHeight() * scaleFloat - mDisplayAttributes.height;
        if (isRecyclerView) {
            if (y - mLastHeightBoundary >= 1 && y > 0) {
                y = (int) mLastHeightBoundary;
            } else if (y < 0 && y + mLastHeightBoundary <= -1) {
                y = (int) -mLastHeightBoundary;
            } else {
            }
        } else {
            if (y < 0 ) {
                return;
            }
            float maxHeight = (getHeight() * (getScaleY() - 1) / 2) -
                    (getHeight() * getScaleY() - mDisplayAttributes.height);
            if (y - mLastHeightBoundary >= 1 && y - maxHeight >= 1 && isbeyondScreen) {
                y = (int) mLastHeightBoundary;
            } else if ((mLastHeightBoundary - y) >= diffHeight && y > 0 && isbeyondScreen) {
                y = (int) maxHeight - scaleDevY;
            } else {
            }
        }

        component.setScale(scale, scale);
        mLastWidthBoundary = (getWidth() * (getScaleX() - 1) / 2);
        mLastHeightBoundary = (int) (getHeight() * (getScaleY() - 1) / 2);

        if (diffHeight > 0) {
            if (!isbeyondScreen) {
                setPosition(x, (mDisplayAttributes.height - getHeight()) / 2);
            } else {
                setPosition(x, y);
                mLastPositionY = getContentPositionY();
            }
        } else {
            setPosition(x, (mDisplayAttributes.height - getHeight()) / 2);
        }
        mLastPositionX = getContentPositionX();
    }
}
